package com.naza.rpc.circuitBreaker;

import com.naza.rpc.util.SystemClock;

/**
 * 
 * 熔断器状态 - 打开
 *
 * @author yl
 */
final class OpenState extends CircuitBreakerState {
    private final long retryAfterWaitDuration;
    private final boolean hasHalfOpenState;

    OpenState(CircuitBreakerImpl circuitBreaker) {
        super(circuitBreaker);
        //scm 上rsf.client.circuitBreaker  duration=5000
        this.retryAfterWaitDuration = SystemClock.getInstance().now() +
                circuitBreaker.getCircuitBreakerConfig().getWaitDurationInOpenState();
        this.hasHalfOpenState = circuitBreaker.getCircuitBreakerConfig().hasHalfOpenState();
    }

    /**
     * Returns false, if the wait duration has not elapsed.
     * Returns true, if the wait duration has elapsed and transitions the state machine to HALF_OPEN state.
     *
     * @return false, if the wait duration has not elapsed. true, if the wait duration has elapsed.
     */
    @Override
    boolean isCallPermitted() {
        // Thread-safe
        if (SystemClock.getInstance().now() > retryAfterWaitDuration) {
            //是否有半打开状态
            if (this.hasHalfOpenState) {
                circuitBreaker.transition(CircuitBreaker.State.OPEN, CircuitBreaker.State.HALF_OPEN);
            } else {
                circuitBreaker.transition(CircuitBreaker.State.OPEN, CircuitBreaker.State.CLOSED);
            }
            return true;
        }
        return false;
    }

    /**
     * Should never be called, because isCallPermitted returns false.
     */
    @Override
    void recordFailure() {
        // Do nothing
    }

    /**
     * Should never be called, because isCallPermitted returns false.
     */
    @Override
    void recordSuccess() {
        // Do nothing
    }

    /**
     * Get the state of the CircuitBreaker
     */
    @Override
    CircuitBreaker.State getState() {
        return CircuitBreaker.State.OPEN;
    }
}
